import axios from 'axios'
import qs from 'qs'
import {Notification, MessageBox, Message, Loading} from 'element-ui'
import store from '@/store'
import { getToken, getLs } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import {tansParams, blobValidate} from "@/utils/util";
import cache from '@/plugins/cache'
import {saveAs} from 'file-saver'
import {sign, signatureGenerate, decryptSM2} from '@/utils/sign'
import config from '@/libs/config'

let downloadLoadingInstance;
// 是否显示重新登录
let isReloginShow;


// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项，表示请求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API + config.common_url,
  headers: {'Content-Type': 'application/json'},
  timeout: 10000
})

// request拦截器
service.interceptors.request.use(config => {
  /**
   * headers 中需要带的参数
   *
   * func-code 请求路径值  ---
   * x-desensitize-flag  undefined  ---
   * cryptoEnabled  是否加密  ---
   * repeatEnabled  undefined ---
   * appId  项目 => VUE_APP_ID ---
   * routerId 路由id 暂时为空
   * signature 签名 ---
   * timestamp  时间戳 ---
   * x-bifang-session ---
   * **/
  const token = getToken()
  // console.log(token, getLs('SM2PublicKey'), getLs('SM2PrivateKey'))
  // 私钥
  const secret = token ? getLs('SM2PrivateKey') : process.env.VUE_APP_SM2_PRIVATE_KEY
  // 公钥
  const secretKey = token ? getLs('SM2PublicKey') : process.env.VUE_APP_SM2_PUBLIC_KEY
  // 获取请求头参数
  const {signature, timestamp, dataSign} = signatureGenerate(config, secret, secretKey)
  // 是否需要防止数据重复提交
  const isRepeatSubmit = (config.headers || {}).repeatSubmit === false

  if (!isRepeatSubmit) {
    // 是否需要设置 token
    const isToken = (config.headers || {}).isToken === false
    if (token && !isToken) {
      config.headers['accessToken'] = token
    }
    config.headers['signature'] = signature
    config.headers['timestamp'] = timestamp
    config.headers['x-bifang-session'] = dataSign
    config.headers['appId'] = process.env.VUE_APP_ID
    // store.permission
    const requestObj = {data: dataSign, time: timestamp}
    const sessionObj = cache.session.getJSON('sessionObj')
    if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
      cache.session.setJSON('sessionObj', requestObj)
    } else {
      const s_data = sessionObj.data
      const s_time = sessionObj.time;                // 请求时间
      const interval = 1000;                         // 间隔时间(ms)，小于此时间视为重复提交
      if (s_data === requestObj.data && requestObj.time - s_time < interval) {
        const message = '数据正在处理，请勿重复提交'
        console.warn(message)
        Message.error({
          message: message
        })
        return Promise.reject(new Error(message))
      } else {
        cache.session.setJSON('sessionObj', requestObj)
      }
    }
  }
  return config
}, error => {
  Promise.reject(error)
})

// 响应拦截器
service.interceptors.response.use(response => {
    /**
     * code : 0
     message: "操作成功！"
     path : null
     result: "04a5"  // 密文
     status: 200
     timestamp:"1706190378237"
     * **/
    const token = getToken()
    // 私钥
    const secret = token ? getLs('SM2PrivateKey') : process.env.VUE_APP_SM2_PRIVATE_KEY
    // 公钥
    // 是否需要解密
    const encrtyStr = response.headers['x-encrty-enabled']
    let res = response.data
    const {code, result, message} = response.data
    if (code && code !== 0 && code !== 200) {
      // 非正常状态  401 403 456 457  < 0
      if (code === 401) {
        if (!isReloginShow) {
          isReloginShow = true;
          MessageBox.confirm('当前用户已登出，请尝试重新登录后再操作。', '提示', {
              confirmButtonText: '重新登录',
              cancelButtonText: '取消',
              type: 'warning'
            }
          ).then(() => {
            isReloginShow = false
            store.dispatch('LogOut').then(() => {
              // 如果是登录页面不需要重新加载
              if (window.location.hash.indexOf("#/login") != 0) {
                location.href = '/index'
              }
            })
          }).catch(() => {
            isReloginShow = false
          })
        }
        // return Promise.reject('当前用户已登出，请尝试重新登录后再操作。')
      }
      if (code === 403) {
        Message({
          message: message || '没有操作权限！',
          type: 'error'
        })
      }
      if (code === 456) {
        // token过期
        if (!isReloginShow) {
          isReloginShow = true;
          MessageBox.confirm('登录已过期，请重新登录后再操作。', '提示', {
              confirmButtonText: '重新登录',
              cancelButtonText: '取消',
              type: 'warning'
            }
          ).then(() => {
            isReloginShow = false
            store.dispatch('LogOut').then(() => {
              // 如果是登录页面不需要重新加载
              if (window.location.hash.indexOf("#/login") != 0) {
                location.href = '/bigscreen/#/login'
              }
            })
          }).catch(() => {
            isReloginShow = false
          })
        }
      }
      if (code === 457) {
        Message({
          message: message,
          type: 'error'
        })
      }
      if (code < 0) {
        Message({
          message: message || '系统异常(后端未返回异常原因)',
          type: 'error'
        })
      }
      return Promise.reject(res)
    } else {
      let resultStr = result
      if (encrtyStr === 'true' && resultStr) {
        //解密报文
        if (resultStr.substr(0, 2) == '04') {
          resultStr = result.substr(2)
        }
        let decryptStr = decryptSM2(resultStr, secret)
        try {
          res.result = JSON.parse(decryptStr)
        } catch (e) {
          res.result = decryptStr
        }
      }
      return res
    }
  },
  error => {
    if (error.response) {
      const data = error.response.data
      const token = getToken()
      if (error.response.status === 401) {
        if (token) {
          store.dispatch('LogOut').then(() => {
            // 如果是登录页面不需要重新加载
            if (window.location.hash.indexOf("#/login") != 0) {
              location.href = '/index';
            }
          })
        }
      } else if (error.response.status === 403) {
        Message.error({
          message: data.path + ',' + data.message
        })
      } else if (error.response.status === 502) {
        Message.error({
          message: '连接服务器失败!'
        })
      } else if (error.response.status === 429) {
        Message.error({
          message: '访问太过频繁，请稍后再试!'
        })
      } else {
        // Message.error({
        //   content: data.message
        // })
        console.log(data.message)
      }
    }
    return Promise.reject(error)
  }
)

// 通用下载方法
export function download(url, params, filename) {
  downloadLoadingInstance = Loading.service({
    text: "正在下载数据，请稍候",
    spinner: "el-icon-loading",
    background: "rgba(0, 0, 0, 0.7)",
  })
  return service.post(url, params, {
    transformRequest: [(params) => {
      return tansParams(params)
    }],
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    responseType: 'blob'
  }).then(async (data) => {
    const isLogin = await blobValidate(data);
    if (isLogin) {
      const blob = new Blob([data])
      saveAs(blob, filename)
    } else {
      const resText = await data.text();
      const rspObj = JSON.parse(resText);
      const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
      Message.error(errMsg);
    }
    downloadLoadingInstance.close();
  }).catch((r) => {
    console.error(r)
    Message.error('下载文件出现错误，请联系管理员！')
    downloadLoadingInstance.close();
  })
}

export default service
